﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransCode.Entitys;
using TransCode.Logic;
using System.IO;


namespace TransCodeTask
{
    public class FFTask
    {

        private string processName = ConfigValue.GetConfigByName("FFPath");

        private string imageArguments = ConfigValue.GetConfigByName("FFImageArguments");

        private string arguments = ConfigValue.GetConfigByName("FFArguments");

        private string cutArguments = ConfigValue.GetConfigByName("FFCutArguments");

        private string getTime = ConfigValue.GetConfigByName("FFGetTime");

        private string mergeAVIArguments = ConfigValue.GetConfigByName("FFMergeAVIArguments");

        public Task task = null;

        private ExecCmd cmd = null;

        private TaskLogic tasklogic = new TaskLogic();

        private bool result = false;

        private int second = -1;

        //-f image2 -i e:\zhangexe\cutimage\image%d.jpg -vcodec libxvid e:\zhangexe\cutimage\vid.avi
        /// <summary>
        /// 图片合成AVI
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="SourceFilePath">合成路径</param>
        /// <returns></returns>
        public bool TaskRunning(string fileName, string SourceFilePath)
        {
            result = false;
            string dir = fileName.Substring(0, fileName.IndexOf('.'));
            if (task != null)
            {
                task.State = 1;
                tasklogic.Save(task);
            }
            cmd = new ExecCmd();
            cmd.processName = processName;
            cmd.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_ErrorDataReceived);
            cmd.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_OutputDataReceived);
            cmd.Exec(string.Format(imageArguments, SourceFilePath + dir + "\\cutimage\\image%d.jpg", SourceFilePath + dir + "\\Complent" + dir + ".avi"));
            return result;
        }

        //ffmpeg.exe -i D:\svn\test.mp4 -vcodec d: \svn\1111.avi
        /// <summary>
        /// MP4转换AVI视频
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="SourceFilePath">转换源路径</param>
        /// <param name="TargetFilePath">转化路径</param>
        /// <returns></returns>
        public bool TaskTranAVI(string fileName, string SourceFilePath, string TargetFilePath)
        {
            result = false;
            string dir = fileName.Substring(0, fileName.IndexOf('.'));
            if (task != null)
            {
                task.State = 1;
                tasklogic.Save(task);
            }
            cmd = new ExecCmd();
            cmd.processName = processName;
            cmd.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_ErrorDataReceived);
            cmd.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_OutputDataReceived);
            cmd.Exec(string.Format(arguments, SourceFilePath + "\\" + fileName, TargetFilePath + dir + ".avi"));
            return result;
        }

        //ffmpeg -ss 01:00:00 -i input_file_h264.mp4 -vcodec copy -acodec copy -t 00:06:00 output_file.mp4
        /// <summary>
        /// 剪切视频
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="SourceFilePath">文件路径</param>
        /// <param name="BeginTime">开始时间</param>
        /// <param name="EndTime">结束时间</param>
        /// <param name="index">第几个</param>
        /// <returns></returns>
        public bool TaskCutAVI(string fileName, string SourceFilePath, string BeginTime, string EndTime, int index)
        {
            result = false;
            string dir = fileName.Substring(0, fileName.IndexOf('.'));
            string targetPath = SourceFilePath + dir + index + "\\";
            if (!Directory.Exists(targetPath))
                Directory.CreateDirectory(targetPath);
            if (task != null)
            {
                task.State = 1;
                tasklogic.Save(task);
            }
            cmd = new ExecCmd();
            cmd.processName = processName;
            cmd.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_ErrorDataReceived);
            cmd.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_OutputDataReceived);
            cmd.Exec(string.Format(cutArguments, BeginTime, SourceFilePath + dir + ".avi", EndTime, targetPath + dir + index + ".avi"));
            return result;
        }

        //ffmpeg -i 3.avi 2>&1 | find /i  "Duration"  Duration：00：10：50，start:0.000000,bitrate:1259 kb/s
        public int TaskGetAVITime(string fileName, string SourceFilePath)
        {
            result = false;
            string dir = fileName.Substring(0, fileName.IndexOf('.'));
            if (task != null)
            {
                task.State = 1;
                tasklogic.Save(task);
            }
            cmd = new ExecCmd();
            cmd.processName = processName;
            cmd.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_ErrorDataReceived);
            cmd.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_OutputDataReceived);
            cmd.Exec(string.Format(getTime, SourceFilePath + dir + ".avi"));
            return second;
        }

        // ffmpeg -i D:/MyVideo1.avi -i D:/MyVideo2.avi -f mp4 -acodec libfaac -vcodec libx264 -sameq D:/Result.avi
        public string TaskMergeAVI(string fileName, string SourceFilePath, string SourceFilePath1, string TargetFilePath, int index)
        {
            result = false;
            if (task != null)
            {
                task.State = 1;
                tasklogic.Save(task);
            }
            string path = TargetFilePath + "Complent" + fileName + index + ".avi";
            cmd = new ExecCmd();
            cmd.processName = processName;
            cmd.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_ErrorDataReceived);
            cmd.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(cmd_OutputDataReceived);
            cmd.Exec(string.Format(mergeAVIArguments, SourceFilePath, SourceFilePath1, path));
            return path;
        }

        public void Dispose()
        {
            cmd.Dispose();
        }

        void cmd_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {

        }

        void cmd_ErrorDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
            if (e == null || e.Data == null)
            {
                if (task != null)
                {
                    task.State = -1;
                    tasklogic.Save(task);
                }
                return;
            }

            if (e.Data.Contains("Duration"))
            {
                string[] datas = e.Data.Split(new char[] { ' ' });
                string time = datas[3].Remove(datas[3].IndexOf('.'));
                string[] timevalues = time.Split(':');
                second = Int32.Parse(timevalues[0]) * 60 * 60 + Int32.Parse(timevalues[1]) * 60 + Int32.Parse(timevalues[2]);
                return;
            }

            if (e.Data.Contains("video:") && e.Data.Contains("audio:") && e.Data.Contains("global headers:") && e.Data.Contains("muxing overhead"))
            {
                if (task != null)
                {
                    task.State = 2;
                    tasklogic.Save(task);
                }
                result = true;
                return;
            }
            //if (e.Data.Contains("end"))
            //{
            //    if (task != null)
            //    {
            //        task.State = 2;
            //        tasklogic.Save(task);
            //    }
            //    result = true;
            //    return;
            //}

            if (e.Data.Length > 0)
            {
                string[] datas = e.Data.Split(new char[] { ' ' });

                double progress = 0;
                if (datas[0] == "frame=")
                {
                    if (double.TryParse(datas[3].Trim(), out progress))
                    {
                        if (task != null)
                        {
                            task.Progress = progress;
                            tasklogic.Save(task);
                        }
                    }
                }
            }
        }
    }
}
